<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:ccts="urn:un:unece:uncefact:documentation:standard:CoreComponentsTechnicalSpecification:2"
	version="2.0">
	
	<xsl:import href="global-vars.xsl"/>
	<xsl:import href="global-templates.xsl"/>
	<xsl:import href="AmountType.xsl" />
	<xsl:import href="CodeType.xsl" />
	<xsl:import href="IDType.xsl" />
	<xsl:import href="MeasureType.xsl" />
	<xsl:import href="NameType.xsl" />
	<xsl:import href="QuantityType.xsl" />
	<xsl:import href="TextType.xsl" />
	
	<xsl:output name="types.format" media-type="application/xhtml+xml" method="xml" 
		encoding="UTF-8" version="1.0" indent="yes" omit-xml-declaration="yes"/>
	
	<xsl:variable name="global.datatypes.used">
		<xsl:call-template name="build-typelist" >
			<xsl:with-param name="element.root" select="/xsd:schema/xsd:element/@name" />
			<xsl:with-param name="element.root.type" select="/xsd:schema/xsd:element/@type" />
		</xsl:call-template>
	</xsl:variable>
	
	<xsl:template name="build-typelist">
		<xsl:param name="element.root" />
		<xsl:param name="element.root.type" />
		
		<xsl:variable name="types">
			<xsl:element name="types">
				<xsl:call-template name="element-types">
					<xsl:with-param name="element.type" select="$element.root.type" />
					<xsl:with-param name="element.schema" select="$global.schema.root" />
				</xsl:call-template>
			</xsl:element>
		</xsl:variable>
		
		<xsl:variable name="codelistTypes">
			<xsl:call-template name="GetCodelistTypes">
				<xsl:with-param name="types.used" select="$types/types/type[not( @name = preceding-sibling::type/@name)]" />
			</xsl:call-template>
		</xsl:variable>
		
		<!-- Filter out all double types and codelistTypes -->
		<xsl:element name="types">
			<xsl:copy-of select="$types/types/type[not( @name = preceding-sibling::type/@name)]" />
			<xsl:element name="codelistTypes">
				<xsl:copy-of select="$codelistTypes/count" />
				<xsl:copy-of 
					select="$codelistTypes/attribute[not( @name = preceding-sibling::attribute/@name
					and @type = preceding-sibling::attribute/@type)]" />
			</xsl:element>
		</xsl:element>
	</xsl:template>
	
	<xsl:template name="element-types">
		<xsl:param name="element.type" />
		<xsl:param name="element.schema" />
		
		<xsl:variable name="element.children">
			<xsl:call-template name="GetChildElements">
				<xsl:with-param name="parent" select="substring-after( $element.type, ':' )" />
				<xsl:with-param name="parent.schema" select="$element.schema" />
			</xsl:call-template>			
		</xsl:variable>
		
		<xsl:for-each select="$element.children/xsd:element">
			<xsl:choose>
				<xsl:when test="xsd:annotation/xsd:documentation/ccts:Acronym = 'BBIE'">
					<xsl:variable name="element.type.schema">
						<xsl:call-template name="GetDataTypeDocument">
							<xsl:with-param name="element.type" select="@type" />
							<xsl:with-param name="element.schema" select="$element.schema" />
						</xsl:call-template>
					</xsl:variable>
					<xsl:element name="type">
						<xsl:attribute name="name" select="@type" />
						<xsl:attribute name="schema" select="$element.type.schema" />
					</xsl:element>
				</xsl:when>
				<xsl:otherwise>
					<xsl:variable name="element.child.ns" 
						select="namespace-uri-for-prefix( substring-before( @type, ':' ), . )"/>
					<xsl:variable name="element.ns" select="if( $element.schema = '' ) 
						then document( $global.schema.root )/xsd:schema/@targetNamespace
						else document( $element.schema )/xsd:schema/@targetNamespace"/>
					<xsl:choose>
						<!-- 
							Test if the child element is declared in the same namespace as it's parent. If not then
							we'll have to look in which document the namespace (and thus the element) is declared.
							Also we'll have to look which prefix is used for that namespace.
						-->
						<xsl:when test="$element.ns != $element.child.ns">
							<xsl:variable name="element.type.schema">
								<xsl:call-template name="GetDataTypeDocument">
									<xsl:with-param name="element.type" select="@type" />
									<xsl:with-param name="element.schema" select="$element.schema" />
								</xsl:call-template>
							</xsl:variable>
							
							<xsl:call-template name="element-types">
								<xsl:with-param name="element.type" select="@type"/>
								<xsl:with-param name="element.schema" select="$element.type.schema" />
							</xsl:call-template>
						</xsl:when>
						<!-- 
							The element is declared in the same document as his parent.
						-->
						<xsl:otherwise>
							<xsl:call-template name="element-types">
								<xsl:with-param name="element.type" select="@type"/>
								<xsl:with-param name="element.schema" select="$element.schema" />
							</xsl:call-template>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:for-each>
	</xsl:template>
	
	<xsl:template name="GetCodelistTypes">
		<xsl:param name="types.used" />
		
		<xsl:for-each select="$types.used">
			<xsl:variable name="type.base">
				<xsl:call-template name="GetUnqualifiedDataType">
					<xsl:with-param name="element.type" select="@name"/>
					<xsl:with-param name="element.type.schema" select="@schema"/>
				</xsl:call-template>
			</xsl:variable>
			<xsl:variable name="type.base" select="substring-after( $type.base, ':' )" />
			
			<xsl:variable name="type.base.codelistattributes">
				<xsl:choose>
					<xsl:when test="$type.base = 'AmountType'">
						<xsl:call-template name="GetAmountTypeAttributes" />
					</xsl:when>
					<xsl:when test="$type.base = 'CodeType'">
						<xsl:call-template name="GetCodeTypeAttributes" />
					</xsl:when>
					<xsl:when test="$type.base = 'IDType'">
						<xsl:call-template name="GetIDTypeAttributes" />
					</xsl:when>
					<xsl:when test="$type.base = 'MeasureType'">
						<xsl:call-template name="GetMeasureTypeAttributes" />
					</xsl:when>
					<xsl:when test="$type.base = 'NameType'">
						<xsl:call-template name="GetNameTypeAttributes" />
					</xsl:when>
					<xsl:when test="$type.base = 'QuantityType'">
						<xsl:call-template name="GetQuantityTypeAttributes" />
					</xsl:when>
					<xsl:when test="$type.base = 'TextType'">
						<xsl:call-template name="GetTextTypeAttributes" />
					</xsl:when>
				</xsl:choose>
			</xsl:variable>
			
			<xsl:variable name="name" select="@name" />
			<xsl:variable name="schema" select="@schema" />
			
			<xsl:for-each select="$type.base.codelistattributes/attributes/attribute">
				<xsl:variable name="type.attribute.info">
					<xsl:call-template name="GetAttributeInfo">
						<xsl:with-param name="type" select="$name"/>
						<xsl:with-param name="type.schema" select="$schema"/>
						<xsl:with-param name="type.attribute" select="." />
					</xsl:call-template>
				</xsl:variable>
				
				<xsl:copy-of select="$type.attribute.info" />
			</xsl:for-each>
		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>
